package com.ztc.util;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import com.ztc.bean.TD;
import com.ztc.bean.TR;

public class TableHtmlUtil {

	/**
	 * html表格转成word表格
	 * @param doc
	 * @param tableEle
	 * @throws Exception
	 */
	public List<TR> tableHtmlAnalyse(String tableHtml) {
		Document doc = Jsoup.parse(tableHtml);
		Elements tableEle = doc.getElementsByTag("table");
		Elements trs = tableEle.first().getElementsByTag("tr");
//		int rowSize = trs.size();
//		int columnSize = 0;
//		for(Element td : trs.first().select("> *")) {
//			if (StringUtils.isNotBlank(td.attr("colspan"))) {
//				columnSize += Integer.parseInt(td.attr("colspan"));
//			} else {
//				columnSize++;
//			}
//		}
		List<TR> trList = new ArrayList<TR>();
		List<TD> dataList = new ArrayList<TD>();
		for(int i = 0; i < trs.size(); i++) {
			Element trEle = trs.get(i);
			TR tr = new TR();
			//获取td
			List<TD> tdList = new ArrayList<TD>();
			Elements tds = trEle.select("> *");
			for(int j = 0; j < tds.size(); j++) {
				Element e = tds.get(j);
				TD td = new TD();
				String styleAttr = e.attr("style");
				if (StringUtils.isNotBlank(e.attr("colspan"))) {
					td.setColspan(Integer.valueOf(e.attr("colspan").trim()));
				}
				if (StringUtils.isNotBlank(e.attr("rowspan"))) {
					td.setRowspan(Integer.valueOf(e.attr("rowspan").trim()));
				}
				Elements inputs = e.getElementsByTag("input");
				if(inputs != null && inputs.size() > 0) {
					String val = inputs.get(0).attr("value");
					td.setContent(val);
				} else {
					td.setContent(e.text());
				}
				
				td.setHtml(e.outerHtml());//e.text();
				if(e.nodeName().equals("td")) {
					td.setX(HorizontalDeduction_td(e));// 步骤1：横向推导，但这个坐标并不是最终坐标，需要进行纵向推导
				} else {
					td.setX(HorizontalDeduction_th(e));
				}
				td.setY(i);// y坐标很简单，就是tr的值
				tdList.add(td);
				dataList.add(td);
			}
			tr.setStyle(trEle.attr("style"));
			tr.setTdList(tdList);
			trList.add(tr);
		}
		// 步骤2：纵向推导
		verticalDeduction(dataList);
		return trList;
	}
	
	/**
	 * @Title : HorizontalDeduction
	 * @Description : 使用递归，进行横坐标的第一步推导，横向推导，同时删除多余的非td元素
	 * @param e
	 * @return
	 */
	private int HorizontalDeduction_td(Element e) {
		Element preElement = e.previousElementSibling();
		if (preElement != null) {
			if (!preElement.tagName().equals("td")) {// 表示td的上一个兄弟节点不是td，则删除这个多余的元素
				preElement.remove();
			} else {
				int nColSpan = 1;// 默认为1
				if (StringUtils.isNotBlank(preElement.attr("colspan"))) {
					nColSpan = Integer.valueOf(preElement.attr("colspan").trim());// 前一个元素的列合并情况
				}
				return HorizontalDeduction_td(preElement) + nColSpan;
			}
		}
		return 0;
	}
	
	/**
	 * @Title : HorizontalDeduction
	 * @Description : 使用递归，进行横坐标的第一步推导，横向推导，同时删除多余的非td元素
	 * @param e
	 * @return
	 */
	private int HorizontalDeduction_th(Element e) {
		Element preElement = e.previousElementSibling();
		if (preElement != null) {
			if (!preElement.tagName().equals("th")) {// 表示td的上一个兄弟节点不是td，则删除这个多余的元素
				preElement.remove();
			} else {
				int nColSpan = 1;// 默认为1
				if (StringUtils.isNotBlank(preElement.attr("colspan"))) {
					nColSpan = Integer.valueOf(preElement.attr("colspan").trim());// 前一个元素的列合并情况
				}
				return HorizontalDeduction_th(preElement) + nColSpan;
			}
		}
		return 0;
	}
	
	/**
	 * @Title : verticalDeduction
	 * @Description : 纵向推导
	 * @param headerList
	 * @return
	 */
	private void verticalDeduction(List<TD> headerList) {
		int headerSize = headerList.size();
		for (int i = 0; i < headerSize; i++) {
			TD tdA = headerList.get(i);
			boolean flag = true;
			while (flag) {// 不断排列当前节点的位置，直到它的位置绝对正确
				flag = false;// 不需要移位
				for (int j = i - 1; j >= 0; j--) {// 找到之前与td的横坐标相等的值
					TD tdB = headerList.get(j);
					if (tdA.getX() == tdB.getX()) {// A找到与其X坐标相等的B
						if (tdB.getRowspan() > tdA.getY() - tdB.getY()) {// 如果B单元格“挡住”了A单元格，才进行移位操作。即：只有B占的行数大于或等于A、B之间的距离，那么B才会挡住A
							flag = true;// 如果存在移位单元格，则仍然需要重新判断当前的位置是否正确。需要移位
							tdA.setX(tdA.getX() + tdB.getColspan());// A的X坐标向后推B.colspan的位置
							int YA = tdA.getY();
							for (int m = i + 1; m < headerSize; m++) {// 同时，与A同处一tr但在其后边的td节点均应向后推B.colspan个位移
								TD td = headerList.get(m);
								if (td.getY() == YA) {
									td.setX(td.getX() + tdB.getColspan());
								}
							}
						}
					}
				}
			}
		}
	}
}
